package david.java.flink_sql.test.leftjoin;

import java.io.*;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Description:
 * @Author: ZhaoDawei
 * @Date: Create in 7:35 下午 2022/10/20
 */
public class Util {

    public static long CombineWatermark = 0;
    public static long watermark1 = 0;
    public static long watermark2 = 0;
    public static Long bound;

    public static void SetBound(long boundVar) {
        bound = boundVar;
    }

    public static void updateWatermark1(long watermark) {
        if (watermark > watermark1) {
            watermark1 = watermark;
//            System.out.println("watermark1->" + watermark1);
            if (bound == null) {
                throw new RuntimeException("bound not set");
            }
            long min = Math.min(watermark1, watermark2) - bound;
            if (min > 0 && min != CombineWatermark) {
                CombineWatermark = min;
                System.err.println("CombineWatermark->" + CombineWatermark);
            }
        }
    }

    public static void updateWatermark2(long watermark) {
        if (watermark > watermark2) {
            watermark2 = watermark;
//            System.out.println("watermark2->" + watermark2);
            if (bound == null) {
                throw new RuntimeException("bound not set");
            }
            long min = Math.min(watermark1, watermark2) - bound;
            if (min > 0 && min != CombineWatermark) {
                CombineWatermark = min;
                System.err.println("CombineWatermark->" + CombineWatermark);
            }
        }
    }

    public static AtomicInteger outputcount = new AtomicInteger();

    static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public synchronized static String getFormatTime() {
        return sdf.format(new Date());
    }

    public synchronized static String format(long timeMs) {
        return sdf.format(timeMs);
    }

    public synchronized static String formatS(long time) {
        return sdf.format(time * 1000);
    }

    public static long getLongTimeS() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
//        calendar.add(Calendar.HOUR,8);
        //aoi 不会回撤
        return calendar.getTime().getTime() / 1000;
    }

    public static long getLongTimeMs() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
//        calendar.add(Calendar.HOUR,8);
        //aoi 不会回撤
        return calendar.getTime().getTime();
    }


    public static String getFileContent(String filePath) {
        File file = new File(filePath);
        StringBuilder sb = new StringBuilder();
        try (FileInputStream fis = new FileInputStream(file); InputStreamReader isr = new InputStreamReader(fis); BufferedReader br = new BufferedReader(isr);) {
            String line;
            while ((line = br.readLine()) != null) {
                sb.append(line).append("\n");
            }
        } catch (Exception e) {
            System.err.println("读取文件出错" + e.getMessage());
        }
        if (sb.length() > 0) {
            return sb.substring(0, sb.length() - 1);
        }
        return sb.toString();
    }

    /**
     * 将驼峰式命名的字符串转换为下划线大写方式。如果转换前的驼峰式命名的字符串为空，则返回空字符串。</br>
     * 例如：HelloWorld->HELLO_WORLD
     *
     * @param name 转换前的驼峰式命名的字符串
     * @return 转换后下划线大写方式命名的字符串
     */
    public static String underscoreName(String name) {
        StringBuilder result = new StringBuilder();
        if (name != null && name.length() > 0) {
            // 将第一个字符处理成小写
            result.append(name.substring(0, 1).toLowerCase());
            // 循环处理其余字符
            for (int i = 1; i < name.length(); i++) {
                String s = name.substring(i, i + 1);
                // 在大写字母前添加下划线
                if (s.equals(s.toUpperCase()) && !Character.isDigit(s.charAt(0))) {
                    result.append("_");
                }
                // 其他字符直接转成小写
                result.append(s.toLowerCase());
            }
        }
        return result.toString();
    }

    /**
     * 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空，则返回空字符串。</br>
     * 例如：HELLO_WORLD->HelloWorld
     *
     * @param name 转换前的下划线大写方式命名的字符串
     * @return 转换后的驼峰式命名的字符串
     */
    public static String camelName(String name) {
        StringBuilder result = new StringBuilder();
        // 快速检查
        if (name == null || name.isEmpty()) {
            // 没必要转换
            return "";
        } else if (!name.contains("_")) {
            // 不含下划线，仅将首字母小写
            return name.substring(0, 1).toLowerCase() + name.substring(1);
        }
        // 用下划线将原始字符串分割
        String camels[] = name.split("_");
        for (String camel : camels) {
            // 跳过原始字符串中开头、结尾的下换线或双重下划线
            if (camel.isEmpty()) {
                continue;
            }
            // 处理真正的驼峰片段
            if (result.length() == 0) {
                // 第一个驼峰片段，全部字母都小写
                result.append(camel.toLowerCase());
            } else {
                // 其他的驼峰片段，首字母大写
                result.append(camel.substring(0, 1).toUpperCase());
                result.append(camel.substring(1).toLowerCase());
            }
        }
        return result.toString();
    }

    public static Object getFiledValue(Object obj, Class clazz, String field) throws Exception {
        Field declaredField = clazz.getDeclaredField(field);
        declaredField.setAccessible(true);
        Object o = declaredField.get(obj);
        return o;
    }


    public static Integer getFiledIntValueNoException(Object obj, Class clazz, String field) {
        try {
            Field declaredField = clazz.getDeclaredField(field);
            declaredField.setAccessible(true);
            Integer o = Integer.valueOf(declaredField.get(obj) + "");
            return o;
        } catch (Exception e) {
            return 0;
        }
    }

    public static Integer getInt(Object obj) {
        if (obj instanceof Integer) {
            return (Integer) obj;
        } else if (obj instanceof Long) {
            return ((Long) obj).intValue();
        }
        return 0;
    }

}
